home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 11 / develop 11 code / MultiBuffer / MultiBuffer Source / PlayFromSynth.c < prev    next >
Encoding:
Text File  |  1992-07-15  |  3.2 KB  |  122 lines  |  [TEXT/MPS ]

  1. //
  2. //
  3. //
  4. //            The Following Code is Specific to Play-from-Wave type operations
  5. //
  6. //
  7. //
  8.  
  9. #pragma load "MacHeaders"
  10.  
  11.  
  12. #ifndef __MAININCLUDES__
  13. #include "MainApp.h"
  14. #endif
  15.  
  16. #ifndef    __DOUBLEBUFFERINCLUDES__
  17. #include "DoubleBuffer.h"
  18. #endif
  19.  
  20. extern     SndChannelPtr    gSndChan;
  21.  
  22. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  23. //    High Level routine that plays a wave form...
  24.  
  25. void PlayWave (long durration, WaveCyclePtr theWave, Ptr *privateData)
  26. {
  27.     OSErr            err;
  28.     SoundHeader        theHeader;
  29.     
  30.     //    Fake a sound header for the wave we're going to play
  31.     theHeader.samplePtr            = nil;
  32.     theHeader.length            = nil;
  33.     theHeader.sampleRate        = (Fixed) 0x56ee8ba3;                    // 22kHz constant
  34.     theHeader.loopStart            = nil;
  35.     theHeader.loopEnd            = nil;
  36.         
  37.     err = DoubleBuffer(gSndChan, (unsigned long)theWave, (ProcPtr)WaveReadProc, (ProcPtr)nil,
  38.                             &theHeader, durration, nil, privateData);
  39. }    
  40.     
  41. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  42. // read procedure for retrieving sound data from the wave spec
  43. OSErr WaveReadProc (void *private, short bufNum, Boolean asynch)
  44. {
  45.     OSErr                             err                         = noErr;
  46.     long                            oldA5                        = nil;
  47.     long                            rdSize                        = 0;
  48.     register strippedDownReadPBPtr    pb                            = nil;
  49.     PrivateDBInfoPtr                dbInfo;
  50.  
  51.     dbInfo = (PrivateDBInfoPtr) private;
  52.  
  53.     if (dbInfo->bytesToGo == 0)                                                // No Bytes to read? bail
  54.         err = eofErr;
  55.     else {
  56.  
  57.         //    Again, optimizing out some of these de-references
  58.         pb = &(dbInfo->buffers[bufNum].readPB.pb);
  59.     
  60.         if (dbInfo->bytesToGo > kBufferSize)
  61.             rdSize = kBufferSize;
  62.         else
  63.             rdSize = dbInfo->bytesToGo;
  64.     
  65.         pb->ioFRefNum = dbInfo->refNum;                                        // set up the paramBlock
  66.         pb->ioBuffer = dbInfo->buffers[bufNum].header->samplePtr;
  67.         pb->ioReqCount = rdSize;
  68.         pb->ioPosMode = fsAtMark;
  69.         pb->ioPosOffset =0;
  70.         dbInfo->buffers[bufNum].readPB.userInfo = (Ptr)dbInfo;
  71.         dbInfo->buffers[bufNum].readPB.headerNum = bufNum;
  72.  
  73.         ReadWave ((WaveCyclePtr) dbInfo->refNum, rdSize, pb->ioBuffer);        // Get the Data 
  74.     
  75.         if (asynch) {
  76.             pb->ioCompletion = (ProcPtr)&CompleteRead;                        // This is a formality
  77.             putPB (pb);                                                        // Stuff PB on (A0)
  78.             CompleteRead ();
  79.         } else
  80.             pb->ioCompletion = nil;
  81.         
  82.         dbInfo->bytesToGo -= rdSize;
  83.     
  84.         dbInfo->buffers[bufNum].header->length =  rdSize;
  85.  
  86.         //    if we were called synchronously, chances are we care about the when we hit the
  87.         //     "End of File", so if rdSize is less than the buffersize we know this was the
  88.         //     last buffer read...
  89.         if (rdSize < kBufferSize)
  90.             err = eofErr;
  91.             
  92.     }
  93.     return (err);
  94. }
  95.  
  96. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  97. //    ReadWave makes a wave snippet look like a continuous wave form to the caller
  98. void ReadWave (WaveCyclePtr theWave, unsigned short reqBytes, Ptr buffer)
  99. {
  100.     static unsigned short    mark                 = 0;
  101.     unsigned short            xferSize            = 0;
  102.     
  103.     while (reqBytes > 0) {
  104.  
  105.         //    Figure out how many bytes to the end of the wave
  106.         xferSize = (theWave->length - mark);
  107.         
  108.         //    Make sure we're "reading" the appropriate number of bytes
  109.         if (reqBytes < xferSize) 
  110.             xferSize = reqBytes;
  111.             
  112.         BlockMove ((theWave->wavePtr + mark), buffer, xferSize);
  113.         
  114.         buffer += xferSize;
  115.         reqBytes -= xferSize;
  116.         
  117.         mark += xferSize;
  118.         if (mark >= theWave->length)
  119.             mark = 0;
  120.     }
  121. }
  122.